import json
import logging
import os
import socket
from pathlib import Path

from django.http import HttpResponse
from django.shortcuts import render, render_to_response

# Create your views here.
from django.template import loader
from django.views.decorators.csrf import csrf_exempt
from django.views.generic.base import View

from core import sword, mvn, scp
from gray_apps.models import *

logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)


class LoginView:
    def get_cookie(self, request):
        login = request.get_signed_cookie('login', salt='**login').split(',')
        username = login[0]
        pwd = login[1]
        users = Users.objects.filter(username=username, password=pwd)
        return users

    def set_cookie(self, username, pwd, response):
        response.set_signed_cookie('login', username + ',' + pwd, salt='**login', max_age=24 * 3600 * 3)
        return response

    def login(request):
        return render(request, 'login/login.html')

    def logout(request):
        t1 = loader.get_template('login/login.html')
        response = HttpResponse(t1.render())
        response.delete_cookie('login', path='/')
        return response

    def current_user(self, request):
        current_usr = None
        if 'login' in request.COOKIES:
            user_filter = self.get_cookie(request)
            current_usr = user_filter.get().username
            return current_usr
        else:
            return current_usr

    # 首页
    def index(self, request):
        if request.method == 'POST':
            if 'login' in request.COOKIES:
                user_filter = self.get_cookie(request)
                if user_filter:
                    user = user_filter.get()
                    list = DeployLog.objects.all()
                    return render(request, 'index.html', {"list": list, "user": user})
                return render(request, 'login/login.html')
            else:
                username = request.POST.get('username', '')
                pwd = request.POST.get('password', '')
                # 判断
                user_filter = Users.objects.filter(username=username, password=pwd)
                if user_filter:
                    user = user_filter.get()
                    list = DeployLog.objects.all()
                    t1 = loader.get_template('index.html')
                    context = {"list": list, "user": user}
                    response = HttpResponse(t1.render(context))
                    return self.set_cookie(username, pwd, response)
                    # response = render_to_response('index.html', {"list": list, "user": user})
                    # return response
                return render(request, 'login/login.html')
        else:
            if 'login' in request.COOKIES:
                user_filter = self.get_cookie(request)
                if user_filter:
                    user = user_filter.get()
                    list = DeployLog.objects.all()
                    return render(request, 'index.html', {"list": list, "user": user})
            return render(request, 'login/login.html')


class ProjectsView:
    # 项目管理列表查看
    def project_list(request):
        list = Projects.objects.all()
        opt_all = DeployOpt.objects.all()
        return render(request, 'project/project_list.html', {"list": list, "opt_all": opt_all})

    # 构建项目
    def project_build(request):
        list = DeployOpt.objects.all()
        return render(request, 'project/project_build.html', {"list": list})

    def pro_search(self, request):
        if request.method == 'GET':
            _project_name = request.GET.get('project_name')
            list = Projects.objects.filter(project_name__contains=_project_name)
            opt_all = DeployOpt.objects.all()
            return render(request, 'project/project_list.html',
                          {"list": list, "opt_all": opt_all, "project_name": _project_name})

    # 构建项目新增
    @staticmethod
    def project_build_add(request):
        if request.method == 'POST':
            project_name = request.POST.get('project_name')
            opt_id = request.POST.get('opt_id')
            log_path = request.POST.get('log_path')
            # 项目
            projects = Projects()
            projects.build_way = request.POST.get('build_way')
            projects.project_name = project_name
            projects.git_addr = request.POST.get('git_addr')
            projects.project_lan = request.POST.get('project_lan')
            projects.install_type = request.POST.get('install_type')
            projects.opt_id = opt_id
            projects.project_desc = request.POST.get('project_desc')
            projects.log_path = log_path
            save = projects.save()
            # 查机器
            get_dpl_opt = DeployOpt.objects.get(id=opt_id)
            opt_name = get_dpl_opt.opt_name

            # 日志
            project_log = ProjectLog()
            project_log.project_name = project_name
            project_log.log_path = log_path
            project_log.opt_name = opt_name
            project_log.save()
        return HttpResponse('{"code":0,"msg":"ok"}', content_type='application/json')

    # 项目描述信息查看
    def project_desc(request):
        list = Projects.objects.get(id=1)
        return render(request, 'project/project_desc.html', {"list": list})


class ProjectLogView:
    # 项目日志管理
    def log_list(request):
        list = ProjectLog.objects.all()
        return render(request, 'project/log_list.html', {"list": list})

    def log_search(self, request):
        if request.method == 'GET':
            _project_name = request.GET.get('project_name')
            list = ProjectLog.objects.filter(project_name__contains=_project_name)
            return render(request, 'project/log_list.html', {"list": list, "project_name": _project_name})


class OptView:

    # 机器列表
    def opt_list(request):
        list = DeployOpt.objects.all()
        return render(request, 'project/opt_list.html', {"list": list})

    # 构建机器z
    def opt_build(request):
        return render(request, 'project/opt_build.html')

    def opt_search(self, request):
        if request.method == 'GET':
            _opt_name = request.GET.get('opt_name')
            list = DeployOpt.objects.filter(opt_name__contains=_opt_name)
            return render(request, 'project/opt_list.html', {"list": list, "opt_name": _opt_name})

    # 构建机器新增
    @staticmethod
    @csrf_exempt
    def opt_build_add(request):
        lg = LoginView()
        if request.method == 'POST':
            if lg.current_user(request) != 'admin':
                return HttpResponse('{"code":-1,"msg":"你没有权限"}', content_type='application/json')
            else:
                projects = DeployOpt()
                projects.opt_name = request.POST.get('opt_name')
                projects.host = request.POST.get('opt_host')
                projects.username = request.POST.get('opt_username')
                projects.pwd_type = request.POST.get('pwd_type')
                projects.password = request.POST.get('opt_password')
                projects.opt_addr = request.POST.get('opt_addr')
                projects.opt_desc = request.POST.get('opt_desc')
                projects.save()
            return HttpResponse('{"code":0,"msg":"ok"}', content_type='application/json')


class DeployView:
    @staticmethod
    def get_localhost():
        hostname = socket.gethostname()
        ip = socket.gethostbyname(hostname)
        return hostname, ip

    # 部署项目
    def project_deploy(request):
        list = Projects.objects.all()
        return render(request, 'project/project_deploy.html', {"list": list})

    # 部署动作
    @staticmethod
    @csrf_exempt
    def project_action(request):
        json_ret = {'code': 0, 'msg': 'ok'}

        if request.method == 'POST':
            pro_id = request.POST.get('pro_id')
            list_project = Projects.objects.get(id=pro_id)
            list_dpl = DeployOpt.objects.get(id=list_project.opt_id)

            git_addr = list_project.git_addr
            opt_addr = list_dpl.opt_addr
            p_name = list_project.project_name
            _first = list_dpl.opt_scp_first
            git_root = opt_addr + p_name
            host = list_dpl.host

            hostname, ip = DeployView.get_localhost()
            if host and host == '127.0.0.1' or host == 'localhost' or host == ip:
                # git clone
                if not Path(git_root).exists():
                    sword.git_clone(git_addr, opt_addr)
                else:
                    sword.reset_pull(git_root)
                    logging.info(sword.git_last_log(git_root))  # 输出最后一条更新日志
                mvn.compile_dependencies(git_root)
                scp.deploy(git_root)
                logging.info("===============本地部署 DONE===============")
                '''发布完之后要记录操作'''
                return HttpResponse(json.dumps(json_ret), content_type='application/json')
            elif host:
                logging.info("SCP远端部署......")
                ping = ' '.join(['ping', '-c', '5', '-W', '10', host])
                exit_code = os.system(ping)
                if exit_code == 0:
                    logging.info("PING HOST {} COUNT {} WAIT TIME {} 网络通畅...".format(host, 10, 10))
                    scp.scp_run(list_dpl, _first, git_root, opt_addr, git_addr)
                    '''发布完之后要记录操作'''
                    logging.info("===============远端部署 DONE===============")
                    return HttpResponse(json.dumps(json_ret), content_type='application/json')
                else:
                    logging.info("PING HOST {} COUNT {} WAIT TIME {} 网络不通...".format(host, 10, 10))
                    json_ret['code'] = -1
                    json_ret['msg'] = 'disconnection'
                    return HttpResponse(json.dumps(json_ret), content_type='application/json')
            else:
                logging.error("host is none")
                json_ret['code'] = -1
                json_ret['msg'] = 'host none'
                return HttpResponse(json.dumps(json_ret), content_type='application/json')
        return HttpResponse(json.dumps(json_ret), content_type='application/json')


class DeployLogView:
    # 项目发布历史记录
    @staticmethod
    def deploy_log(request):
        list = DeployLog.objects.all()
        return render(request, 'project/deploy_list.html', {"list": list})

    def deploy_search(self, request):
        if request.method == 'GET':
            _project_name = request.GET.get('project_name')
            list = DeployLog.objects.filter(project_name__contains=_project_name)
            return render(request, 'project/deploy_list.html', {"list": list, "project_name": _project_name})

    # 日志调取
    @staticmethod
    def log_pull(request):

        response_data = {}
        if request.method == 'GET':
            pro_id = request.GET.get("pro_id")
            list_project = Projects.objects.get(id=pro_id)
            project_log_path = list_project.log_path
            try:
                if not Path(project_log_path).exists():
                    return HttpResponse('file path: ' + project_log_path + ' is not file, pls check!')
            except IOError:
                pass
            else:
                ret = DeployLogView.get_nu(project_log_path)
                logging.info(ret)
                if ret:
                    response_data['data'] = ret.splitlines()
                else:
                    response_data['data'] = ''
                return HttpResponse(json.dumps(response_data), content_type="application/json")
        else:
            return HttpResponse('illegal http method')

    @staticmethod
    def get_nu(project_log_path):
        # wc = ['sed', '-n', '$=', 'stdout.log']
        # r = sword.execute_cmd(wc, cwd=project_log_path, timeout=300)
        args = ['tail', '-100', 'stdout.log']
        ret = sword.execute_cmd(args, cwd=project_log_path, timeout=300)
        return ret


class UsersView:
    # 人员查看
    def users_list(request):
        list = Users.objects.all()
        return render(request, 'users/users_list.html', {"list": list})

    def usr_search(self, request):
        if request.method == 'GET':
            _username = request.GET.get('username')
            list = Users.objects.filter(username__contains=_username)
            return render(request, 'users/users_list.html', {"list": list, "username": _username})
